package org.dftproject.lineagelinkage.adapter;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import org.dftproject.genesis.data.genealogy.GenealogyUtils;
import org.dftproject.genesis.data.genealogy.IInstant;
import org.dftproject.genesis.data.genealogy.IPerson;
import org.dftproject.genesis.data.genealogy.IPlace;
import org.dftproject.genesis.data.genealogy.IRole;
import org.dftproject.genesis.data.genealogy.Sex;

import edu.byu.cs428.twenty_gen.datamodel.pedigree.Gender;
import edu.byu.cs428.twenty_gen.datamodel.pedigree.view.interfaces.IEvent;
import edu.byu.cs428.twenty_gen.datamodel.pedigree.view.interfaces.IName;
import edu.byu.cs428.twenty_gen.datamodel.pedigree.view.interfaces.ISimpleIndividual;

public class GenIndividual implements Serializable, ISimpleIndividual {

	private static final long serialVersionUID = -1249439208417405460L;

	IPerson person;

	private List<ISimpleIndividual> m_children;

	private List<ISimpleIndividual> m_siblings;

	private List<ISimpleIndividual> m_spouses;

	public GenIndividual(IPerson person, boolean isBase) {
		assert (person != null);
		this.person = person;
		setChildren();
		setSiblings();
		setSpouses();
	}

	public GenIndividual(IPerson person) {
		assert (person != null);
		this.person = person;
	}

	public ISimpleIndividual getBiologicalFather() {
		IPerson father = GenealogyUtils.getFather(person);
		if (father != null) {
			return new GenIndividual(father);
		}
		return null;
	}

	public ISimpleIndividual getBiologicalMother() {
		IPerson mother = GenealogyUtils.getMother(person);
		if (mother != null) {
			return new GenIndividual(mother);
		}
		return null;
	}

	public List<ISimpleIndividual> getAdoptingFathers() {
		throw new UnsupportedOperationException();
	}

	public List<ISimpleIndividual> getAdoptingMothers() {
		throw new UnsupportedOperationException();
	}

	public IEvent getBirth() {
		throw new UnsupportedOperationException();
	}

	public IEvent getBurial() {
		throw new UnsupportedOperationException();
	}

	private void setChildren() {
		Set<IPerson> children = GenealogyUtils.getChildren(person);
		if (children != null && children.size() > 0) {
			m_children = new ArrayList<ISimpleIndividual>();
			for (IPerson person : children) {
				if (person != null) {
					m_children.add(new GenIndividual(person));
				}
			}
		}
	}

	public List<ISimpleIndividual> getChildren() {
		return m_children;
	}

	public List<ISimpleIndividual> getCouplesChildren(ISimpleIndividual spouse) {
		throw new UnsupportedOperationException();
	}

	public List<IEvent> getCustomEvents() {
		throw new UnsupportedOperationException();
	}

	public IEvent getDeath() {
		throw new UnsupportedOperationException();
	}

	public Gender getGender() {
		Sex sex = GenealogyUtils.getSex(person);
		if (sex != null) {
			return (sex == Sex.Male) ? Gender.MALE : Gender.FEMALE;
		}
		return null;
	}

	public IEvent getMarriage() {
		throw new UnsupportedOperationException();
	}

	public IName getName() {
		org.dftproject.genesis.data.genealogy.IName name = GenealogyUtils.getName(person);
		if (name != null) {
			return new GenName(name);
		}
		return null;
	}

	public List<IEvent> getProxyEvents() {
		throw new UnsupportedOperationException();
	}

	private void setSiblings() {
		Set<IPerson> siblings = GenealogyUtils.getSiblings(person);
		if (siblings != null && siblings.size() > 0) {
			m_siblings = new ArrayList<ISimpleIndividual>();
			for (IPerson person : siblings) {
				if (person != null) {
					m_siblings.add(new GenIndividual(person));
				}
			}
		}
	}

	public List<ISimpleIndividual> getSiblings() {
		return m_siblings;
	}

	private void setSpouses() {
		Set<IPerson> spouses = GenealogyUtils.getSpouses(person);
		if (spouses != null && spouses.size() > 0) {
			m_spouses = new ArrayList<ISimpleIndividual>();
			for (IPerson person : spouses) {
				if (person != null) {
					m_spouses.add(new GenIndividual(person));
				}
			}
		}
	}

	public List<ISimpleIndividual> getSpouses() {
		return m_spouses;
	}

	public List<IEvent> getStandartEvents() {
		Set<IRole> roles = person.getRoles();
		if (roles != null && roles.size() > 0) {
			List<IEvent> events = new ArrayList<IEvent>();
			for (IRole role : roles) {
				if (role != null) {
					org.dftproject.genesis.data.genealogy.IEvent event = role.getEvent();
					if (event != null) {
						IInstant instance = GenealogyUtils.getDate(event);
						IPlace place = GenealogyUtils.getPlace(event);
						if (place != null || instance != null) {
							events.add(new GenEvent(instance, place));
						}
					}
				}
			}
			return events;
		}
		return null;
	}

}
